<?php

namespace app\api\service;

use app\api\model\Plan;
use common\exception\ExceptionEmun;
use common\exception\PlanException;
use common\helper\DateHelper;
use common\service\BaseService;
use common\Token\Token;
use common\traits\InstanceTrait;
use think\Db;

class PlanService extends BaseService
{

    use InstanceTrait;

    public function save($post)
    {
        $data = $post;
        $where = [
            ['plan_id', '=', $post['plan_id']],
        ];
        if ($ret = Plan::get($post['plan_id'])) {
            Plan::instance()->allowField(true)->save($data, $where);
        } else {
            $member_info = Token::instance()->getUserInfo();
            $data['member_id'] = $member_info['member_id'];
            $data['status'] = 1;
            $data['finish_time'] = $_SERVER['REQUEST_TIME'];
            Plan::create($data);
        }
        return true;
    }

    public function getInfo($get)
    {
        $plan_id = $get['plan_id'];
        $Plan = Plan::get($plan_id);
        if ($Plan) {
            $Plan->delete();
        } else {
            ExceptionEmun::throwException(PlanException::NO_EXIST);
        }
        return $Plan;
    }

    public function delete($post)
    {
        $plan_id = $post['plan_id'];
        $Plan = Plan::get($plan_id);
        if (empty($Plan)) {
            ExceptionEmun::throwException(PlanException::NO_EXIST);
        }
        $Plan->delete();
        return $Plan;
    }

    /**
     * 获取挑战列表
     * @param type $state
     * @param type $user_id
     * @return type
     */
    public function getList($get)
    {
        $member_info = Token::instance()->getUserInfo();
        $get['member_id'] = $member_info['member_id'];
        $list = Plan::instance()->getList($get);
        return $list;
    }

    /**
     * 更改挑战的状态,如果有周期则写入新的挑战
     * @param type $user_id
     * @param type $id
     * @return type
     */
    public function finish($post)
    {
        $plan_id = $post['plan_id'];
        $member_id = Token::instance()->getUserInfo()['member_id'];
        Db::startTrans();
        $plan = Plan::get($plan_id);
        if (empty($plan)) {
            ExceptionEmun::throwException(PlanException::NO_EXIST);
        }
        if ($member_id != $plan->member_id) {
            ExceptionEmun::throwException(PlanException::NO_RIGHT);
        }
        $data = [
            'status' => 2,
            'finish_time' => $_SERVER['REQUEST_TIME'],
        ];
        $plan->save($data);
        $ret = $this->writeCycle($plan);
        Db::commit();
        return true;
    }

    /**
     * 根据挑战状态和周期判断是否需要写入新的挑战
     * @param type $plan_model
     */
    public function writeCycle($plan)
    {
        if ($plan['status'] == 2 && !empty($plan['cycle'])) {
            $finish_time = DateHelper::to_time($plan['finish_time']);
            $endline = DateHelper::to_time(DateHelper::to_date($_SERVER['REQUEST_TIME'], "Y-m-d 23:59:59"));
//              生成任务日期必须是今天往后
            while ($finish_time <= $endline) {
                $finish_time = strtotime("+ " . $plan['cycle'] . " day", $finish_time);
            }
            $data = [
                'status' => 1,
                'finish_time' => $finish_time,
                'content' => $plan['content'],
                'cycle' => $plan['cycle'],
                'member_id' => $plan['member_id'],
                'pid' => $plan['plan_id'],
            ];
            $one = Plan::where($data)->find();
            $ret = '';
            if (empty($one)) {
                $ret = Plan::create($data);
            }
        }
        return true;
    }

    /**
     * 计算一段时间内,统计每一天的情况
     * @param type $where
     * @param type $start_date
     * @param type $end_date
     * @return type
     */
    public static function count_daily($where, $start_date, $end_date)
    {
        $start_timestamp = to_time($start_date);
        $end_timestamp = to_time($end_date);
//        $where_time = [
//            [ 'finish_time', 'between time', [ $start_date, $end_date ] ],
//        ];
        $field = [
            'count(id)' => 'count',
            'from_unixtime(finish_time, "%c月%e日" )' => 'date',
        ];
        $res = Plan::whereTime('finish_time', 'between', [$start_date, $end_date])
                   ->where($where)
                   ->group('from_unixtime(finish_time, "%c-%e" )')
                   ->field($field)
                   ->select()
                   ->toArray();
        $res = array_column($res, 'count', 'date');
        $temp_timestamp = $start_timestamp;
        $dailyCount = [];
        while ($temp_timestamp <= $end_timestamp) {
            $temp_date = to_date($temp_timestamp, "n月j日");
            $month_day = to_date($temp_timestamp, "j日");
            $dailyCount[$month_day] = 0;
            if (!empty($res[$temp_date])) {
                $temp = $res[$temp_date];
                $dailyCount[$month_day] = round($temp);
            }
            $temp_timestamp += 86400;
        }
        return $dailyCount;
    }

    /**
     * 某年内,统计每个月的情况
     * @param array $where
     * @param type $year
     * @param type $count
     * @return type
     */
    public static function count_year($where = [], $year = null, $count = 'count(id)')
    {
        $time_column = "finish_time";
        $time_format = "from_unixtime";
        if (empty($year)) {
            $year = date('Y');
        }
        $time_arr = [
            date($year . "-1-1 00:00:00"),
            date($year . "-12-31 23:59:59"),
        ];
        $result = Plan::where($where)
                      ->whereTime('finish_time', 'between', $time_arr)
                      ->group('temp_month')
                      ->field("$time_format($time_column,'%c') as temp_month,$count as value")
                      ->select();
        $result = array_column($result->toArray(), 'value', 'temp_month');
        $year_value = [];
        for ($i = 1; $i <= 12; $i++) {
            $index = $i;
            if (!empty($result[$index])) {
                $temp = $result[$index];
                $year_value[$i . "月"] = money_float($temp);
            } else {
                $year_value[$i . "月"] = 0;
            }
        }
        return $year_value ?: [];
    }

}
